package com.campusexpresspickup.service.impl;

import com.campusexpresspickup.exception.logisticsException;
import com.campusexpresspickup.mapper.UserRoleResourceRelationMapper;
import com.campusexpresspickup.config.OauthUserDetails;
import com.campusexpresspickup.dto.UpdateUserPasswordParam;
import com.campusexpresspickup.dto.UserParam;
import com.campusexpresspickup.entity.LogisticsCourier;
import com.campusexpresspickup.entity.OauthRole;
import com.campusexpresspickup.entity.OauthUser;
import com.campusexpresspickup.entity.OauthUserRole;
import com.campusexpresspickup.entity.UserResource;
import com.campusexpresspickup.entity.UserRoleMenuRelation;
import com.campusexpresspickup.entity.UserRoleResourceRelation;
import com.campusexpresspickup.exception.Asserts;
import com.campusexpresspickup.mapper.OauthUserMapper;
import com.campusexpresspickup.mapper.OauthUserRoleMapper;
import com.campusexpresspickup.mapper.UserResourceMapper;
import com.campusexpresspickup.mapper.UserRoleMenuRelationMapper;
import com.campusexpresspickup.page.OauthUserPage;
import com.campusexpresspickup.service.ILogisticsCourierService;
import com.campusexpresspickup.service.IOauthUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campusexpresspickup.util.JwtTokenUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lq
 * @since 2021-11-15
 */
@Service
public class OauthUserServiceImpl extends ServiceImpl<OauthUserMapper, OauthUser> implements
    IOauthUserService {

  private final PasswordEncoder passwordEncoder;
  private final JwtTokenUtil jwtTokenUtil;

  private final OauthUserMapper oauthUserMapper;
  private final OauthUserRoleMapper oauthUserRoleMapper;
  private final UserResourceMapper userResourceMapper;
  private final UserRoleResourceRelationMapper userRoleResourceRelationMapper;
  private final UserRoleMenuRelationMapper userRoleMenuRelationMapper;
  private final ILogisticsCourierService logisticsCourierService;

  public OauthUserServiceImpl(
      PasswordEncoder passwordEncoder,
      JwtTokenUtil jwtTokenUtil, OauthUserMapper oauthUserMapper,
      OauthUserRoleMapper oauthUserRoleMapper,
      UserResourceMapper userResourceMapper,
      UserRoleResourceRelationMapper userRoleResourceRelationMapper,
      UserRoleMenuRelationMapper userRoleMenuRelationMapper,
      ILogisticsCourierService logisticsCourierService) {
    this.passwordEncoder = passwordEncoder;
    this.jwtTokenUtil = jwtTokenUtil;
    this.oauthUserMapper = oauthUserMapper;
    this.oauthUserRoleMapper = oauthUserRoleMapper;
    this.userResourceMapper = userResourceMapper;
    this.userRoleResourceRelationMapper = userRoleResourceRelationMapper;
    this.userRoleMenuRelationMapper = userRoleMenuRelationMapper;
    this.logisticsCourierService = logisticsCourierService;
  }


  @Override
  public OauthUser getUserByUsername(String account) {
    List<OauthUser> oauthUser = oauthUserMapper.findUserByUserName(account);
    if (oauthUser != null && oauthUser.size() > 0) {
      return oauthUser.get(0);
    }
    return null;
  }

  @Override
  public OauthUser register(UserParam userParam) {
    OauthUser oauthUser = new OauthUser();
    oauthUser.setAccount(userParam.getAccount());
    oauthUser.setUserName(userParam.getUserName());
    oauthUser.setPassword(userParam.getPassword());
    oauthUser.setGender(userParam.getGender());
    oauthUser.setPhone(userParam.getPhone());
    oauthUser.setCreateTime(new Date());
    oauthUser.setStatus(false);//用户状态：false ->
    oauthUser.setUserType(userParam.getUserType());
    List<OauthUser> userByUserName = oauthUserMapper.findUserByUserName(oauthUser.getAccount());
    if (userByUserName.size() > 0) {
      throw new logisticsException("账号名称已存在");
    }
    oauthUser.setPassword(passwordEncoder.encode(oauthUser.getPassword()));
    oauthUserMapper.insert(oauthUser);
    OauthUserRole oauthUserRole = new OauthUserRole();
    oauthUserRole.setUserId(oauthUser.getId());
    UserRoleMenuRelation userRoleMenuRelation = new UserRoleMenuRelation();
    UserRoleResourceRelation userRoleResourceRelation = new UserRoleResourceRelation();
    if ("1".equals(String.valueOf(userParam.getUserType()))) {//小程序用户
      oauthUserRole.setRoleId(3);
      userRoleMenuRelation.setRoleId(3);
      userRoleResourceRelation.setRoleId(3);
    } else if ("2".equals(String.valueOf(userParam.getUserType()))) {//快递员
      oauthUserRole.setRoleId(4);
      userRoleMenuRelation.setRoleId(4);
      userRoleResourceRelation.setRoleId(4);
      LogisticsCourier logisticsCourier = new LogisticsCourier();
      logisticsCourier.setUserName(userParam.getUserName());
      logisticsCourier.setPassword(passwordEncoder.encode(userParam.getPassword()));
      logisticsCourier.setCreateTime(new Date());
      logisticsCourier.setPhone(oauthUser.getPhone());
      logisticsCourier.setCourierId(oauthUser.getId());
      logisticsCourier.setGender(oauthUser.getGender());
      logisticsCourierService.getBaseMapper().insert(logisticsCourier);
    } else {
      oauthUserRole.setRoleId(2);
      userRoleMenuRelation.setRoleId(2);
      userRoleResourceRelation.setRoleId(2);
    }
    oauthUserRoleMapper.insert(oauthUserRole);
    userRoleMenuRelation.setMenuId(6);
    userRoleMenuRelationMapper.insert(userRoleMenuRelation);
    userRoleResourceRelation.setResourceId(1);
    userRoleResourceRelationMapper.insert(userRoleResourceRelation);
    return null;
  }

  @Override
  public String login(String account, String password) {
    UserDetails userDetails = loadUserByUsername(account);
    if (!passwordEncoder.matches(password, userDetails.getPassword())) {
      Asserts.error("密码不正确");
    }
    if (!userDetails.isEnabled()) {
      Asserts.error("账号被禁用,请联系管理员");
    }

    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
        userDetails, null, userDetails.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    return jwtTokenUtil.generateToken(userDetails);
  }

  @Override
  public String refreshToken(String oldToken) {
    return jwtTokenUtil.refreshHeadToken(oldToken);
  }

  @Override
  public OauthUser getItem(Integer id) {
    return oauthUserMapper.selectById(id);
  }

  @Override
  public List<OauthUser> list(OauthUserPage userPage) {
    return oauthUserMapper.findUserList(userPage);
  }

  @Override
  public int update(Integer id, OauthUser oauthUser) {
    oauthUser.setId(id);
    OauthUser user = oauthUserMapper.selectById(id);
    if (user != null) {
      try {
        if (!user.getPassword().equals(oauthUser.getPassword())) {
          oauthUser.setPassword(passwordEncoder.encode(oauthUser.getPassword()));
        }
      } catch (logisticsException e) {
        throw new logisticsException("该用户输入的密码与原密码相同");
      }
    }
    return oauthUserMapper.updateById(oauthUser);
  }

  @Override
  public int delete(Integer id) {
    return oauthUserMapper.deleteById(id);
  }

  @Override
  public int updateRole(Integer userId, List<Integer> roleIds) {
    int count = roleIds == null ? 0 : roleIds.size();
    oauthUserRoleMapper.deleteBatchIds(roleIds);
    List<OauthUserRole> list = new ArrayList<>();
    if (!CollectionUtils.isEmpty(roleIds)) {
      for (Integer id : roleIds) {
        OauthUserRole oauthUserRole = new OauthUserRole();
        oauthUserRole.setRoleId(id);
        oauthUserRole.setUserId(userId);
        list.add(oauthUserRole);
      }
    }
    oauthUserRoleMapper.insertList(list);
    return count;
  }

  @Override
  public List<OauthRole> getRoleList(Integer userId) {
    return oauthUserRoleMapper.getRoleList(userId);
  }

  @Override
  public List<UserResource> getResourceList(Integer adminId) {
    List<UserResource> resourceList = userResourceMapper.getResourceList(adminId);
    if (resourceList != null && resourceList.size() > 0) {
      return resourceList;
    }
    return null;
  }

  @Override
  public int updatePassword(UpdateUserPasswordParam user) {
    if (StringUtils.isEmpty(user.getAccount()) || StringUtils.isEmpty(user.getNewPassWord())
        || StringUtils.isEmpty(user.getOldPassWord())) {
      return -1;
    }
    List<OauthUser> userByUserName = oauthUserMapper.findUserByUserName(user.getAccount());
    if (CollectionUtils.isEmpty(userByUserName)) {
      return -2;
    }

    if (!passwordEncoder.matches(user.getOldPassWord(), userByUserName.get(0).getPassword())) {
      return -3;
    }
    OauthUser oauthUser = userByUserName.get(0);
    oauthUser.setPassword(passwordEncoder.encode(user.getNewPassWord()));
    oauthUserMapper.updateById(oauthUser);
    return 1;
  }

  @Override
  public OauthUserDetails loadUserByUsername(String account) {
    OauthUser oauthUser = getUserByUsername(account);
    if (oauthUser != null) {
      List<UserResource> resourceList = getResourceList(oauthUser.getId());
      return new OauthUserDetails(oauthUser, resourceList);
    }
    throw new UsernameNotFoundException("用户名或密码错误");
  }
}
